问题: 什么是正则表达式的分组,如何用()实现简单分组?
👇 点击展开/折叠 面试背诵模板(建议先背这个)
正则分组指用圆括号 `()` 将模式中的子表达式括起来,将其视为一个整体单元。核心作用有两方面:一是组合量化,让量词(如 `+`、`*`)作用于整个括号内的子表达式(如 `(ab)+` 可匹配 `abab`);二是捕获提取,匹配成功后,括号内匹配的具体子串会被保存,可通过 `group(1)`、`group(2)` 等编号提取。分组编号默认按左括号出现的顺序从 1 开始递增。
捕获组编号规则与代码示例
括号按左括号出现的先后顺序编号(从 1 开始)。group(0) 或 group() 返回完整匹配结果。
1 2 3 4 5 6 7 8 9
| import re text = "2024-10-01" pattern = r'(\d{4})-(\d{2})-(\d{2})' match = re.search(pattern, text)
print(match.group(0)) print(match.group(1)) print(match.group(2)) print(match.group(3))
|
分组提取与 findall 的行为差异
当使用 re.findall() 且模式中包含多个捕获组时,返回的不再是字符串列表,而是元组列表,每个元组对应一个匹配项中各分组的内容。
1 2 3 4 5 6 7
| text = "日期: 2024-10-01, 2025-12-31" results = re.findall(r'(\d{4})-(\d{2})-(\d{2})', text) print(results)
for year, month, day in results: print(f"年: {year}, 月: {month}, 日: {day}")
|
基础应用:提取用户名与域名
1 2 3 4 5
| text = "联系: zhangsan@qq.com" match = re.search(r'(\w+)@(\w+\.\w+)', text) if match: print(match.group(1)) print(match.group(2))
|
非捕获分组 (?:...)(拓展对比)
若只需组合量化而无需提取子串,可使用 (?:...) 非捕获分组,避免占用编号并提升性能。
| 写法 |
是否捕获 |
适用场景 |
(pattern) |
✅ 是(默认捕获) |
需要提取括号内匹配的子串 |
(?:pattern) |
❌ 否 |
仅需将子表达式作为整体量化,无需提取 |
1 2 3
| pattern = r'go(?:o)?' print(re.findall(pattern, 'go goo'))
|